package es.tikitaka.dao.impl;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.Query;

import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Name;

import es.tikitaka.dao.EquipoService;
import es.tikitaka.dictionary.AniosDic;
import es.tikitaka.domain.Temporada;
import es.tikitaka.domain.equipo.Equipo;

/**
 * 
 * @author Saúl Domínguez
 * @since 2010
 * @category PFC
 */
@Name("equipoService")
public class EquipoServiceImpl implements EquipoService {

	@In
	EntityManager em;

	/**
	 * Constructor por defecto
	 */
	public EquipoServiceImpl() {
		// TODO Auto-generated constructor stub
	}

	/**
	 * Método para listar todos los equipos almacenados en el sistema
	 * 
	 * @return lista de todos los equipos
	 */
	@SuppressWarnings("unchecked")
	public List<Equipo> getList() {
		List<Equipo> list = null;
		try {
			list = em.createQuery("select e from Equipo e order by e.nombre")
					.getResultList();
		} catch (RuntimeException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return list;
	}

	/**
	 * Método para buscar los equipos coincidentes con los criterios de búsqueda
	 * 
	 * @param nombre
	 *            Nombre del equipo
	 * @param fundacion
	 *            Año de fundación
	 * @param temporada
	 *            Temporada para la que se tienen datos
	 * @param s
	 *            Consulta ha realizar
	 * @return lista de equipos coincidentes con los criterios de búsqueda
	 */
	@SuppressWarnings("unchecked")
	public List<Equipo> buscar(String nombre, AniosDic fundacion,
			Temporada temporada, StringBuffer s) {

		List<Equipo> listaEquipos = null;

		try {
			Query q = em.createQuery(s.toString());

			if (nombre != null && nombre.length() > 0) {
				q.setParameter("1", nombre);
			}
			if (fundacion != null) {
				q.setParameter("2", fundacion.getId());
			}
			if (temporada != null) {
				q.setParameter("3", temporada.getId());
			}

			listaEquipos = q.getResultList();

		} catch (RuntimeException e) {
			// TODO: handle exception
			e.printStackTrace();
		}

		return listaEquipos;
	}

	/**
	 * Método para buscar los equipos activos coincidentes con el patrón de
	 * búsqueda
	 * 
	 * @param buscar
	 *            Cadena de texto a buscar
	 * @return lista de los equipos coincidentes
	 */
	@SuppressWarnings("unchecked")
	public List<Equipo> buscarActivos(String buscar) {

		List<Equipo> lista = null;

		try {
			lista = em
					.createQuery(
							"select e from Equipo e where upper(e.nombre) like upper('%'||?1||'%') and e.activo = 'true' order by e.nombre")
					.setParameter("1", buscar).getResultList();
		} catch (RuntimeException e) {
			e.printStackTrace();
		}

		return lista;
	}

	/**
	 * Método para buscar los equipos activos coincidentes con el patrón de
	 * búsqueda y que ademas no tenga asociada ya la temporada que se está
	 * pasando por parámetro
	 * 
	 * @param buscar
	 *            Cadena de texto a buscar
	 * @param temporada
	 *            Temporada asociada
	 * @return lista de los equipos coincidentes
	 */
	@SuppressWarnings("unchecked")
	public List<Equipo> buscarActivosSinTemporada(String buscar,
			Temporada temporada) {

		List<Equipo> lista = null;

		try {
			lista = em
					.createQuery(
							"select e from Equipo e where upper(e.nombre) like upper('%'||?1||'%') "
									+ "and e.activo = 'true' and e.id not in (select p.equipo from PartEquipo p, Temporada t where t.id =?2 and p.temporada = t.id) order by e.nombre")
					.setParameter("1", buscar).setParameter("2",
							temporada.getId()).getResultList();
		} catch (RuntimeException e) {
			e.printStackTrace();
		}

		return lista;
	}

	/**
	 * Método que comprueba si el nombre del equipo existe ya en el sistema
	 * 
	 * @param nombre
	 *            Nombre del equipo a comprobar
	 * @return estado de la comprobación (true or false)
	 */
	@SuppressWarnings("unchecked")
	public boolean existeNombre(String nombre) {

		List<Equipo> list = null;
		try {
			list = em.createQuery("select e from Equipo e where e.nombre = ?1")
					.setParameter("1", nombre).getResultList();

			if (list != null && list.size() > 0) {
				return true;
			} else {
				return false;
			}
		} catch (RuntimeException e) {
			e.printStackTrace();
		}
		return false;
	}

	public Equipo merge(Equipo equipo) {

		em.refresh(equipo);
		return em.merge(equipo);

	}

	/**
	 * Método para eliminar del sistema un equipo existente
	 * 
	 * @param id
	 *            Id del equipo a eliminar
	 * @return estado de la operación (true or false)
	 */
	public boolean delete(Integer id) {
		boolean correcto;
		try {
			Equipo equipo = em.getReference(Equipo.class, id);
			em.remove(equipo);
			em.flush();
			correcto = true;
		} catch (RuntimeException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			correcto = false;
		}
		return correcto;
	}

	/**
	 * Método para guardar un nuevo equipo o las modificaciones sufridas por un
	 * equipo ya existente
	 * 
	 * @param equipo
	 *            Equipo a guardar
	 * @return estado de la operación (true or false)
	 */
	public boolean save(Equipo equipo) {
		boolean correcto;
		try {
			em.persist(equipo);
			em.flush();
			correcto = true;
		} catch (RuntimeException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			correcto = false;
		}
		return correcto;
	}
}
